#include "mgr.h"
#include <memory>

using namespace std;

void Mgr::create_pool(int num) { work_queue_.create(num); }

void Mgr::destroy_pool() { work_queue_.destroy(); }

void Mgr::suspend_pool() {
  DWORD code = 0;
  for (uint32 i = 0; i < threads_num_; i++) {
    GetExitCodeThread(work_queue_.threads_[i], &code);
    if (code == STILL_ACTIVE) {
      SuspendThread(work_queue_.threads_[i]);
    }
  }
}

void Mgr::resume_pool() {
  DWORD code = 0;
  for (uint32 i = 0; i < threads_num_; i++) {
    GetExitCodeThread(work_queue_.threads_[i], &code);
    if (code == STILL_ACTIVE) {
      ResumeThread(work_queue_.threads_[i]);
    }
  }
}

void Mgr::run_worker(const string &file_path, const string &file_root_path,
                     const string &script) {
  // FIXME: 不优雅, 应该使用软停止.
  create_pool(1);
  CWaitForEvent::get()->start();
  worker_ = new LuaWorker(file_path, file_root_path, game_, api_);
  // 如果有 script, 就执行 dostring
  worker_->set_script(script);
  // 工作线程
  work_queue_.insert_work_item(worker_);
}

void Mgr::stop_all_scripts() {
  CWaitForEvent::get()->stop();
  // FIXME: 不优雅, 应该使用软停止.
  destroy_pool();
}

std::shared_ptr<Api> Mgr::api() const { return api_; }

std::shared_ptr<Game> Mgr::game() const { return game_; }

uint64 Mgr::base() const { return base_; }

HWND Mgr::window() const { return window_; }

uint32 Mgr::pid() const { return pid_; }

void Mgr::init(uint32 pid, HWND window, uint64 base) {
  pid_ = pid;
  window_ = window;
  base_ = base;
  game_ = std::make_shared<Game>(pid, window, base);
  api_ = std::make_shared<Api>(base, game_);
}

Mgr::Mgr() {
  CWaitForEvent::get()->create();
  CWaitForEvent::get()->start();
  threads_num_ = 3;
  // create_pool(threads_num_);
}

Mgr::~Mgr() {
  destroy_pool();
  CWaitForEvent::get()->stop();
  CWaitForEvent::get()->close();
}
